package cn.chenxing.sftp;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @Description SFTP
 * @Author maogen.ymg
 * @Date 2020/3/14 17:26
 */
@Slf4j
public class SFTP {

    /** SFTP 登录用户名 */
    private String username;
    /** SFTP 登录密码 */
    private String password;
    /** SFTP 服务器地址IP地址 */
    private String host;
    /** SFTP 端口 */
    private int port;
    /** SFTP 远端保存文件目录 */
    private String remoteDirectory;

    /** 是否已经连接 */
    private Boolean isConnected = false;

    /**
     * 创建一个SFTP
     */
    private ChannelSftp sftp;
    /**
     * 创建一个SFTP会话
     */
    private Session session;

    /**
     *  获取一个SFTP连接
     * @return ChannelSftp
     */
    public ChannelSftp getConnection(){
        // 加载配置
        configSftp();
        return connect();
    }

    /**
     * 关闭一个SFTP连接
     */
    public void disconnect(){
        closeConnect();
    }

    /**
     * 返回连接状态，是否已连接
     * @return isConnected
     */
    public Boolean getIsConnected() {
        return isConnected;
    }

    /**
     * 获取远端存储目录
     * @return remoteDirectory
     */
    public String getRemoteDirectory() {
        // 读取配置
        configSftp();
        return remoteDirectory;
    }

    /**
     * SFTP基本配置
     */
    private void configSftp() {
        Properties properties = new Properties();
        // 使用ClassLoader加载properties配置文件生成对应的输入流
        InputStream in = SFTP.class.getResourceAsStream("/sftpConfig.properties");
        try {
            // 使用properties对象加载输入流
            properties.load(in);
            username = properties.getProperty("sftp.username");
            password = properties.getProperty("sftp.password");
            host = properties.getProperty("sftp.host");
            port = Integer.parseInt(properties.getProperty("sftp.port"));
            remoteDirectory = properties.getProperty("sftp.remoteDirectory");

        } catch (IOException e){
            log.info("SFTP配置配置文件读取错误{}", e.getMessage(), e);
        }
    }

    /**
     * 连接SFTP服务器
     * @return ChannelSftp
     */
    private ChannelSftp connect() {

        try {
            JSch jsch = new JSch();
            session = jsch.getSession(username, host, port);
            if(password != null) {
                session.setPassword(password);
            }

            Properties sshConfig = new Properties();
            // 设置第一次登陆的时候提示，可选值：(ask | yes | no)
            sshConfig.put("StrictHostKeyChecking", "no");
            // 优先使用 password 验证
            sshConfig.put("PreferredAuthentications","password");
            session.setConfig(sshConfig);
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect(15000);
            sftp = (ChannelSftp) channel;
            log.info("[sftp] sftp登陆成功, host:{}, username: {}", host, username);

        } catch (Exception e) {
            log.error("[sftp] sftp登陆失败{}", e.getMessage(), e);
        }

        isConnected = true;
        return sftp;
    }

    /**
     * 关闭连接 SFTP server
     */
    private void closeConnect() {
        try {
            if (sftp != null && sftp.isConnected()) {
                sftp.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
            sftp = null;
            session = null;
            log.info("[sftp] sftp退出成功, host:{}, username: {}", host, username);
        } catch (Exception e) {
            log.error("[sftp] sftp退出失败{}", e.getMessage(), e);
        }

        isConnected = false;
    }


}
